using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.Xml;
using System.ServiceModel.Channels;
using System.Diagnostics;
using System.IO;
using System.Xml.Schema;
using System.ServiceModel.Description;
using Microsoft.MSE.Catalog.Contracts;
using Microsoft.MSE.Catalog.Module;

namespace Microsoft.MSE.Catalog.Services
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, AddressFilterMode = AddressFilterMode.Any)]
    public class WCFCatalogSvc : IWCFCatalogSvc, IRepositoryChangedSvc
    {
        private ISubscriptionManager _subscriptionManager;
        private INotificationManager _notificationManager;
        private object _eventingLock = new object();

        public WCFCatalogSvc(Uri baseAddress)
        {
        }

        private ISubscriptionManager Subscriptions
        {
            get
            {
                if (_subscriptionManager != null)
                    return _subscriptionManager;
                lock (_eventingLock)
                {
                    if (_subscriptionManager != null)
                        return _subscriptionManager;
                    //try to obtain reference registered as an Extension before defaulting to our own implmenetation
                    _subscriptionManager = OperationContext.Current.Host.Extensions.Find<ISubscriptionManager>();
                    if (_subscriptionManager == null)
                        _subscriptionManager = new SubscriptionManager();
                    return _subscriptionManager;
                }
            }
        }
        private INotificationManager Notifications
        {
            get
            {
                if (_notificationManager != null)
                    return _notificationManager;
                lock (_eventingLock)
                {
                    if (_notificationManager != null)
                        return _notificationManager;
                    //try to obtain reference registered as an Extension before defaulting to our own implmenetation
                    _notificationManager = OperationContext.Current.Host.Extensions.Find<INotificationManager>();
                    if (_notificationManager == null)
                        _notificationManager = new NotificationManager(this.Subscriptions);
                    return _notificationManager;
                }
            }
        }

        #region Private Members
        private static MseEventData BuildNotificationData(DBEventContext dbNotification)
        {
            MseEventData mseEvent = new MseEventData(MapDbEventToEventTopics(dbNotification.Event, dbNotification.ChangeType));
            //fill out notification details;

            foreach (DBEventDataItem dbItem in dbNotification.EventData)
            {
                //Process RuntimeServer event data
                RuntimeServerEventData rsItem = mseEvent.RuntimeServers.Find(data => data.Id == dbItem.RuntimeServerId.ToString());

                if (rsItem == null)
                {
                    rsItem = new RuntimeServerEventData();
                    rsItem.Id = dbItem.RuntimeServerId.ToString();
                    mseEvent.RuntimeServers.Add(rsItem);
                }

                //Process Endpoint event data
                //move on to next dbItem if no endpoint id
                if (dbItem.EndpointId == Guid.Empty)
                    continue;
                EndpointEventData epItem = rsItem.Endpoints.Find(data => data.Id == dbItem.EndpointId.ToString());

                if (epItem == null)
                {
                    epItem = new EndpointEventData();
                    epItem.Id = dbItem.EndpointId.ToString();
                    rsItem.Endpoints.Add(epItem);
                }

                //Process Operation event data
                //move on to next dbItem if no operation id
                if (dbItem.OperationId == Guid.Empty)
                    continue;
                OperationEventData opItem = epItem.Operations.Find(data => data.Id == dbItem.OperationId.ToString());
                if (opItem == null)
                {
                    opItem = new OperationEventData();
                    opItem.Id = dbItem.OperationId.ToString();
                    epItem.Operations.Add(opItem);
                }
            }
            return mseEvent;
        }
        private static EventTopics MapDbEventToEventTopics(DBEvents item, DBChangeType changeType)
        {
            switch (item)
            {
                case DBEvents.RuntimeServersUpdated:
                    return EventTopics.RuntimeUpdated;
                case DBEvents.EndpointsUpdated:
                    switch (changeType)
                    {
                        case DBChangeType.Create:
                            return EventTopics.RuntimeEndpointAdded;
                        case DBChangeType.Delete:
                            return EventTopics.RuntimeEndpointRemoved;
                        default:
                            return EventTopics.RuntimeEndpointChanged;
                    }
                case DBEvents.OperationsUpdated:
                    return EventTopics.RuntimeEndpointOperationChanged;
                case DBEvents.EndpointOpAssociationUpdated:
                    switch (changeType)
                    {
                        case DBChangeType.Delete:
                            return EventTopics.RuntimeEndpointOperationDeActivated;
                        default:
                            return EventTopics.RuntimeEndpointOperationChanged;
                    }
                case DBEvents.EndpointOpPublicationUpdated:
                    switch (changeType)
                    {
                        case DBChangeType.Create:
                            return EventTopics.RuntimeEndpointOperationPublished;
                        case DBChangeType.Delete:
                            return EventTopics.RuntimeEndpointOperationUnPublished;
                        default:
                            return EventTopics.RuntimeEndpointOperationChanged;
                    }
                default:
                    return EventTopics.RuntimeUpdated;
            }
        }
        #endregion

        #region MSEEventing Members

        public void AcceptEvent(AcceptEventMsg request)
        {
            if (request == null || request.AcceptEvent == null)
            {
                TraceHelper.TraceError("Invalid event notification received from DB.");
                return;
            }

            TraceHelper.TraceInformation("Event Notification for " + request.AcceptEvent.Event.ToString() + " received from DB");
            switch (request.AcceptEvent.Event)
            {  
                case DBEvents.EndpointOpAssociationUpdated:
                case DBEvents.EndpointOpPublicationUpdated:
                case DBEvents.EndpointsUpdated:
                    try
                    {
                        MseEventData notificationData = BuildNotificationData(request.AcceptEvent);
                        Notifications.RaiseEvent(notificationData);
                        Dictionary<Guid, Guid> endpoints = new Dictionary<Guid, Guid>();
                        foreach (DBEventDataItem dbEventDataItem in request.AcceptEvent.EventData)
                        {
                            if (dbEventDataItem.EndpointId != Guid.Empty &&
                                endpoints.ContainsKey(dbEventDataItem.EndpointId) == false)
                            {
                                // This is disabled for now
                                //DAL.PublishEndPointToUddi(dbEventDataItem.EndpointId, false, null, null);
                                endpoints.Add(dbEventDataItem.EndpointId, dbEventDataItem.EndpointId);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        string msg = ex.Message;
                        throw ex;
                    }
                    break;
                case DBEvents.OperationsUpdated:
                    try
                    {
                        MseEventData notificationData = BuildNotificationData(request.AcceptEvent);
                        Notifications.RaiseEvent(notificationData);
                    }
                    catch (Exception ex)
                    {
                        string msg = ex.Message;
                        throw ex;
                    }
                    break;
                case DBEvents.RuntimeServersUpdated:
                    try
                    {
                        MseEventData notificationData = BuildNotificationData(request.AcceptEvent);
                        Notifications.RaiseEvent(notificationData);
                        Dictionary<Guid, Guid> runtimeservers = new Dictionary<Guid, Guid>();
                        foreach (DBEventDataItem dbEventDataItem in request.AcceptEvent.EventData)
                        {
                            if (dbEventDataItem.RuntimeServerId != Guid.Empty &&
                                runtimeservers.ContainsKey(dbEventDataItem.RuntimeServerId) == false)
                            {
                                DAL.PublishRuntimeServerEndPointsToUddi(dbEventDataItem.RuntimeServerId, false, null, null);
                                runtimeservers.Add(dbEventDataItem.RuntimeServerId, dbEventDataItem.RuntimeServerId);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        string msg = ex.Message;
                        throw ex;
                    }
                    break;
                //case DBEvents.EndpointPolicyUpdated:
                //    sSubscriptionManager.RaiseEvent(Enum.GetName(request.AcceptEvent.Event.GetType(), request.AcceptEvent.Event));
                //    break;
                //case DBEvents.ServiceDefinitionUpdated:
                //    sSubscriptionManager.RaiseEvent(Enum.GetName(request.AcceptEvent.Event.GetType(), request.AcceptEvent.Event));
                //    break;
                //case DBEvents.ServicePolicyUpdated:
                //    sSubscriptionManager.RaiseEvent(Enum.GetName(request.AcceptEvent.Event.GetType(), request.AcceptEvent.Event));
                //    break;
                default:
                    throw new ApplicationException("Unknown Event Received [" + Enum.GetName(typeof(DBEvents), request.AcceptEvent.Event) + "]");
            }
        }

        public SubscribeResponseMsg Subscribe(SubscribeRequestMsg request)
        {
            return new SubscribeResponseMsg(Subscriptions.Subscribe(request.Subscribe));
        }

        public RenewResponseMsg Renew(RenewRequestMsg request)
        {
            if (request.ReferenceParameters == null) throw new WSEInvalidMessageFault(SC.CatalogSvcActor, "ReferenceParameters Header was not supplied");
            return new RenewResponseMsg(Subscriptions.Renew(request.Renew, request.ReferenceParameters));
        }

        public void Unsubscribe(UnsubscribeRequestMsg request)
        {
            if (request.ReferenceParameters == null) throw new WSEInvalidMessageFault(SC.CatalogSvcActor, "ReferenceParameters Header was not supplied");
            Subscriptions.Unsubscribe(request.Unsubscribe, request.ReferenceParameters);
        }

        public GetStatusResponseMsg GetStatus(GetStatusRequestMsg request)
        {
            if (request.ReferenceParameters == null) throw new WSEInvalidMessageFault(SC.CatalogSvcActor, "ReferenceParameters Header was not supplied");
            return new GetStatusResponseMsg(Subscriptions.GetStatus(request.GetStatus, request.ReferenceParameters));
        }

        #endregion


        #region IWCFCatalogSvc Members

        public Guid GetIDFromName(string entityName, EntityClass entityClass)
        {
            try
            {
                return DAL.GetIDFromName(entityName, entityClass, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }
        
        public RuntimeServerList ListRuntimeServers() {
            try {
                return DAL.ListRuntimeServers(null, null);
            } catch (ApplicationException aex) {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            } catch (Exception ex) {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateRuntimeServer(RuntimeServer runtimeServer) {
            try {
                return DAL.CreateRuntimeServer(runtimeServer, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateSchema(Schema schema)
        {
            try
            {
                return DAL.CreateSchema(schema, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteRuntimeServer(Guid ID)
        {
            try
            {
                DAL.DeleteRuntimeServer(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public RuntimeServer UpdateRuntimeServer(RuntimeServer runtimeServer)
        {
            try
            {
                return DAL.UpdateRuntimeServer(runtimeServer, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public RuntimeServer GetRuntimeServer(Guid ID) {
            try {
                return DAL.GetRuntimeServer(ID,true, null, null);
            } catch (ApplicationException aex) {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public RuntimeServer GetRuntimeServerWithoutEndpointWSDL(Guid ID)
        {
            try
            {
                return DAL.GetRuntimeServer(ID,false, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Schema GetSchema(Guid ID)
        {
            try {
                return DAL.GetSchema(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public RuntimeServer GetRuntimeServerByName(string name)
        {
            try
            {
                Guid ID = DAL.GetIDFromName(name, EntityClass.RuntimeServer, null, null);
                return DAL.GetRuntimeServer(ID,true, null, null);
            } catch (ApplicationException aex) {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public EndpointList ListEndpoints()
        {
            try
            {
                return DAL.ListEndpoints(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public EndpointList ListEndpointsForRuntimeServer(string runtimeServerName)
        {
            try
            {
                Guid runtimeServerID = DAL.GetIDFromName(runtimeServerName, EntityClass.RuntimeServer, null, null);
                return DAL.ListEndpointsForRuntimeServerID(runtimeServerID,null, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateEndpoint(Endpoint endpoint)
        {
            try
            {
                return DAL.CreateEndpoint(endpoint, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteEndpoint(Guid ID)
        {
            try
            {
                DAL.DeleteEndpoint(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Endpoint UpdateEndpoint(Endpoint endpoint)
        {
            try
            {
                return DAL.UpdateEndpoint(endpoint, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }        

        public Endpoint GetEndpoint(Guid ID, Guid runtimeServerID)
        {
            try
            {
                return DAL.GetEndpoint(ID, runtimeServerID, true, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }


        public Endpoint GetEndpointWithoutWSDL(Guid ID)
        {
            try
            {
                return DAL.GetEndpoint(ID, Guid.Empty, false, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Endpoint GetEndpoint(string name)
        {
            try {
                Guid ID = DAL.GetIDFromName(name, EntityClass.RuntimeServer, null, null);
                return DAL.GetEndpoint(ID,Guid.Empty,true, null, null);
            } catch (ApplicationException aex) {
                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public SchemaList ListSchemas()
        {
            try
            {
                return DAL.ListSchemas(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Schema UpdateSchema(Schema schema)
        {
            try
            {
                Schema oldSchema = DAL.GetSchema(schema.ID, null, null);
                List<string> errors = CompareSchemas(oldSchema, schema);

                if (errors.Count > 0)
                {
                    string errMsg = "";
                    foreach (string msg in errors)
                    {
                        errMsg += "  " + msg + ";";
                    }
                    throw new ApplicationException("Can not update Schema: ");
                }

                return DAL.UpdateSchema(schema, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        private List<string> CompareSchemas(Schema oldSchemaObj, Schema newSchemaObj)
        { //string oldSchemaXML, string newSchemaXML) {
            try
            {
                List<string> result = new List<string>();
                XmlSchema oldSchema = XmlSchema.Read(new StringReader(oldSchemaObj.XSD.OuterXml), null);
                XmlSchema newSchema = XmlSchema.Read(new StringReader(newSchemaObj.XSD.OuterXml), null);

                // This is not necessary as both of these schemas have already been validated
                //XmlSchemaSet oldSchemaSet = new XmlSchemaSet();
                //XmlSchemaSet newSchemaSet = new XmlSchemaSet();
                //oldSchemaSet.Add(oldSchema);
                //newSchemaSet.Add(newSchema);
                //try {
                //    oldSchemaSet.Compile();
                //} catch (XmlSchemaException ex) {
                //    result.Add("Old schema is not valid: " + ex.Message);
                //    return result;
                //}
                //try {
                //    newSchemaSet.Compile();
                //} catch (XmlSchemaException ex) {
                //    result.Add("New schema is not valid: " + ex.Message);
                //    return result;
                //}

                XmlSchemaObjectTable oldElementTable = oldSchema.Elements;
                XmlSchemaObjectTable newElementTable = newSchema.Elements;

                foreach (XmlQualifiedName name in oldElementTable.Names)
                {
                    if (ElementInUse(oldSchemaObj.ID, name.Name))
                    {
                        XmlSchemaElement oldElement = (XmlSchemaElement)oldElementTable[name];
                        if (newElementTable.Contains(name))
                        {
                            XmlSchemaElement newElement = (XmlSchemaElement)newElementTable[name];
                            if (!oldElement.SchemaTypeName.Equals(newElement.SchemaTypeName))
                            {
                                result.Add(name.Name + " is of different type in new Schema");
                            }
                        }
                        else
                        {
                            result.Add(name.Name + " is missing from new Schema");
                        }
                    }
                }

                return result;
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }



        private bool ElementInUse(Guid ID, string element)
        {
            try
            {
                bool result = false;
                OperationList operationList = DAL.ListOperationsByElement(ID, element, null, null);

                if ((operationList.Operations != null) && (operationList.Operations.Count > 0)) result = true;
                return result;
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid ImportSchema(XmlElement schema, string preferredPrefix)
        {
            try
            {

                Schema newSchema;
                Schema oldSchema;
                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(schema.OuterXml);
                XmlNamespaceManager xmlns = new XmlNamespaceManager(xdoc.NameTable);
                xmlns.AddNamespace("xs", XmlSchema.Namespace);
                string namespaceURI = xdoc.SelectSingleNode("/xs:schema/@targetNamespace", xmlns).Value;
                Guid id = DAL.GetIDFromName(namespaceURI, EntityClass.Schema, null, null);

                if (!id.Equals(Guid.Empty))
                {
                    oldSchema = DAL.GetSchema(id, null, null);
                    XmlDocument xdoc2 = new XmlDocument();
                    xdoc2.LoadXml(oldSchema.XSD.OuterXml);

                    xdoc = MergeSchemas(xdoc, xdoc2);

                    newSchema = new Schema();
                    newSchema.ID = id;
                    newSchema.NamespaceURI = namespaceURI;
                    newSchema.XSD = xdoc.DocumentElement;
                    newSchema.PreferredPrefix = preferredPrefix;
                    return DAL.UpdateSchema(newSchema, null, null).ID;

                    //oldSchema = DAL.GetSchema(id, null, null);
                    //newSchema = new Schema();
                    //newSchema.NamespaceURI = namespaceURI;
                    //newSchema.XSD = schema;
                    //newSchema.Description = oldSchema.Description;
                    //if (!string.IsNullOrEmpty(preferredPrefix)) {
                    //    newSchema.PreferredPrefix = preferredPrefix;
                    //} else {
                    //    newSchema.PreferredPrefix = oldSchema.PreferredPrefix;
                    //    newSchema.ID = oldSchema.ID;
                    //}
                    //List<string> errors = CompareSchemas(oldSchema, newSchema);
                    //if (errors.Count > 0) {
                    //    string errMsg = "";
                    //    foreach (string msg in errors) {
                    //        errMsg += "  " + msg + ";";
                    //    }
                    //    throw new ApplicationException("Can not update Schema: ");
                    //} else {
                    //    DAL.UpdateSchema(newSchema, null, null);
                    //    return newSchema.ID;
                    //}
                }
                else
                {
                    newSchema = new Schema();
                    newSchema.NamespaceURI = namespaceURI;
                    newSchema.XSD = xdoc.DocumentElement;
                    newSchema.PreferredPrefix = preferredPrefix;
                    return DAL.CreateSchema(newSchema, null, null);
                }
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        private XmlDocument MergeSchemas(XmlDocument schema1, XmlDocument schema2)
        {
            XmlNamespaceManager xmlns = new XmlNamespaceManager(schema1.NameTable);
            xmlns.AddNamespace("xsd", XmlSchema.Namespace);

            foreach (XmlNode node in schema2.SelectNodes("/xsd:schema/child::*", xmlns))
            {
                bool skip = false;
                foreach (XmlNode node2 in schema1.SelectNodes("/xsd:schema/xsd:" + node.LocalName, xmlns))
                {
                    string name1 = null;
                    string name2 = null;
                    if (node.Attributes["name"] != null) name1 = node.Attributes["name"].Value;
                    if (node2.Attributes["name"] != null) name2 = node2.Attributes["name"].Value;
                    if ((!string.IsNullOrEmpty(name1)) && (!string.IsNullOrEmpty(name2)) && (name1.Equals(name2)))
                    { // same "element", is it different
                        skip = true;
                        if (node.InnerXml.Equals(node2.InnerXml))
                        {
                            TraceHelper.TraceInformation("Ingoring second definition of " + node.Name + " " + name1 + " as it is a duplicate of the first");
                        }
                        else
                        {
                            string oldDef = node.InnerXml;
                            string newDef = node2.InnerXml;
                            TraceHelper.TraceWarning("Ingoring second definition of " + node.Name + " " + name1 + ", however it may be defined differently: old definition [{0}] - new definition [{1}]", oldDef, newDef);
                        }
                    }
                }
                if (!skip)
                {
                    XmlElement xl = node as XmlElement;
                    if (xl != null)
                    {
                        XmlNode nxl = schema1.CreateElement(xl.Prefix, xl.LocalName, xl.NamespaceURI);
                        foreach (XmlAttribute xattr in xl.Attributes)
                        {
                            XmlAttribute nxattr = schema1.CreateAttribute(xattr.Prefix, xattr.LocalName, xattr.NamespaceURI);
                            nxattr.Value = xattr.Value;
                            nxl.Attributes.Append(nxattr);
                        }
                        nxl.InnerXml = xl.InnerXml;
                        if (string.Compare(nxl.LocalName, "import", false) == 0 &&
                            string.Compare(nxl.NamespaceURI, XmlSchema.Namespace, true) == 0)
                        {
                            // It is import node so it should be at the very beginning
                            DAL.AppendImportElementToSchema(schema1, nxl);
                        }
                        else
                        {
                            schema1.SelectSingleNode("/xsd:schema", xmlns).AppendChild(nxl);
                        }
                    }
                }
            }

            return schema1;
        }

        public void DeleteSchema(Guid ID)
        {
            try
            {
                DAL.DeleteSchema(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }
        
        public OperationList ListOperations()
        {
            try
            {
                return DAL.ListOperations(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public List<OperationListElement> ListOperationsByGroup(Guid ID)
        {
            try
            {
                return DAL.ListOperationsByGroup(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationList ListOperationsBySchema(Guid ID)
        {
            try
            {
                return DAL.ListOperationsBySchema(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateOperation(Operation operation)
        {
            try
            {
                return DAL.CreateOperation(operation, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteOperation(Guid ID)
        {
            try
            {
                DAL.DeleteOperation(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Operation UpdateOperation(Operation operation)
        {
            try
            {
                return DAL.UpdateOperation(operation, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Operation GetOperation(Guid ID)
        {
            try
            {
                return DAL.GetOperation(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateOperationVersion(OperationVersion operationVersion)
        {
            try
            {
                return DAL.CreateOperationVersion(operationVersion, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteOperationVersion(Guid ID)
        {
            try
            {
                DAL.DeleteOperationVersion(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationVersion UpdateOperationVersion(OperationVersion operationVersion)
        {
            try
            {
                return DAL.UpdateOperationVersion(operationVersion, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationVersion GetOperationVersion(Guid ID)
        {
            try
            {
                return DAL.GetOperationVersion(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void AssignAssociatedOperationVerToEndpoint(Guid operationVersionID, Guid endpointID)
        {
            try
            {
                DAL.AssignAssociatedOperationVersionToEndpoint(operationVersionID, endpointID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void AssignPublishedOperationVerToEndpoint(Guid operationVersionID, Guid endpointID)
        {
            try
            {
                DAL.AssignPublishedOperationVersionToEndpoint(operationVersionID, endpointID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void RemoveAssociatedOperationVerForEndpoint(Guid operationVersionID, Guid endpointID)
        {
            try
            {
                DAL.RemoveAssociatedOperationVersionFromEndpoint(operationVersionID, endpointID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void RemovePublishedOperationVerForEndpoint(Guid operationVersionID, Guid endpointID)
        {
            try
            {
                DAL.RemovePublishedOperationVersionFromEndpoint(operationVersionID, endpointID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public ChannelList ListChannels()
        {
            try
            {
                return DAL.ListChannels(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateChannel(Channel channel)
        {
            try
            {
                return DAL.CreateChannel(channel, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteChannel(Guid ID)
        {
            try
            {
                DAL.DeleteChannel(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Channel UpdateChannel(Channel chnl)
        {
            try
            {
                return DAL.UpdateChannel(chnl, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Channel GetChannel(Guid ID)
        {
            try
            {
                return DAL.GetChannel(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public PolicyList ListPolicies()
        {
            try
            {
                return DAL.ListPolicies(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreatePolicy(Policy policy)
        {
            try
            {
                return DAL.CreatePolicy(policy, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeletePolicy(Guid ID)
        {
            try
            {
                DAL.DeletePolicy(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Policy UpdatePolicy(Policy policy)
        {
            try
            {
                return DAL.UpdatePolicy(policy, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Policy GetPolicy(Guid ID)
        {
            try
            {
                return DAL.GetPolicy(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public MSEBindingList ListMSEBindings()
        {
            try
            {
                return DAL.ListMSEBindings(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Guid CreateMSEBinding(MSEBinding binding)
        {
            try
            {
                return DAL.CreateMSEBinding(binding, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteMSEBinding(Guid ID)
        {
            try
            {
                DAL.DeleteMSEBinding(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public MSEBinding UpdateMSEBinding(MSEBinding binding)
        {
            try
            {
                return DAL.UpdateMSEBinding(binding, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public MSEBinding GetMSEBinding(Guid ID)
        {
            try
            {
                return DAL.GetMSEBinding(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }
    
        public List<OperationVersion> GetOperationVersionsForEndpointAndAction(Guid endpointID, string action)
        {
            try
            {
                return DAL.GetOperationVersionsForEndpointAndAction(endpointID, action, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public List<OperationVersion> GetOperationVersionsForEndpointAndFirstBodyElement(Guid endpointID, string elementName, string namespaceURI)
        {
            try
            {
                return DAL.GetOperationVersionsForEndpointAndFirstBodyElement(endpointID, elementName, namespaceURI, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public Boolean ValidateOperationVersionRequest(XmlElement request, Guid opVersionID)
        {
            try
            {
                return DAL.ValidateOperationVersionRequest(request, opVersionID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationGroup CreateOperationGroup(OperationGroup operationGroup)
        {
            try
            {
                return DAL.CreateOperationGroup(operationGroup, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationGroup GetOperationGroup(Guid ID)
        {
            try
            {
                return DAL.GetOperationGroup(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void DeleteOperationGroup(Guid ID)
        {
            try
            {
                DAL.DeleteOperationGroup(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationGroup UpdateOperationGroup(OperationGroup operationGroup)
        {
            try
            {
                return DAL.UpdateOperationGroup(operationGroup, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationGroupList ListOperationGroups()
        {
            try
            {
                return DAL.ListOperationGroups(null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public OperationGroupList ListOperationGroupsByOperation(Guid operationID)
        {
            try
            {
                return DAL.ListOperationGroupsByOperation(operationID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void PublishRuntimeServerEndPointsToUddi(Guid ID, bool refresh)
        {
            try
            {
                DAL.PublishRuntimeServerEndPointsToUddi(ID, refresh, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));
                
                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public void RemoveRuntimeServerEndPointsFromUddi(Guid ID)
        {
            try
            {
                DAL.RemoveRuntimeServerEndPointsFromUddi(ID, null, null);
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }

        public bool IsUddiIntegrationEnabled()
        {
            try
            {
                if (Configurator.svcConfig.serviceCatalogUddi != null &&
                    Configurator.svcConfig.serviceCatalogUddi.UddiIntegrationMode == true)
                    return true;
                else
                    return false;
            }
            catch (ApplicationException aex)
            {
                TraceHelper.TraceError("An application error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(aex));

                string subFaultCode = SC.DefaultSubFaultCode;

                if (aex.Data.Contains(SC.SubFaultCodeKey)) subFaultCode = aex.Data[SC.SubFaultCodeKey] as string;
                throw new FaultException(aex.Message, FaultCode.CreateReceiverFaultCode(new FaultCode(subFaultCode, MseConstants.MSENamespace)));
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError("An unexpected error occurred in Catalog Service Operation [{0}]. Error Detail [{1}]", MethodInfo.GetCurrentMethod().Name, DAL.GetExceptionDetails(ex));

                throw new FaultException(ex.Message, FaultCode.CreateSenderFaultCode(new FaultCode(SC.UnknownSubFaultCode, MseConstants.MSENamespace)));
            }
        }
        #endregion


    }


}
